package com.web.exiaodao.remote.service.impl;

import com.alibaba.fastjson.JSON;
import com.web.exiaodao.business.constant.JConstant;
import com.web.exiaodao.business.entity.FavoriteTable;
import com.web.exiaodao.business.entity.InsHotelRoomsTable;
import com.web.exiaodao.business.entity.Institution;
import com.web.exiaodao.business.repository.InsHotelRoomsTableRepository;
import com.web.exiaodao.business.repository.InstitutionRepository;
import com.web.exiaodao.remote.service.ApiBannerService;
import com.web.exiaodao.remote.service.ApiCommentService;
import com.web.exiaodao.remote.service.ApiFavoriteTableService;
import com.web.exiaodao.remote.service.ApiInstitutionService;
import com.web.exiaodao.remote.vo.BannerVo;
import com.web.exiaodao.remote.vo.CommentVo;
import com.web.exiaodao.remote.vo.InsHotelRoomsTableVo;
import com.web.exiaodao.remote.vo.InstitutionVo;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.service.impl.BaseService;
import com.web.webstart.base.util.SqlResultUtil;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.WebUitl;
import com.web.webstart.base.util.result.XaResult;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.web.exiaodao.business.constant.JConstant.COMMENT_SUM_SCORE;

/**
 * @author: zhangl
 * @times: 2016-11-04 10:01:30
 * 类的说明：前端APIInstitution接口实现类
 **/
@Service("ApiInstitutionService")
@Transactional(readOnly = false)
public class ApiInstitutionServiceImpl extends BaseService<Institution> implements ApiInstitutionService {

    private static final Logger LOGGER = Logger.getLogger(ApiInstitutionServiceImpl.class);

    @Autowired
    InstitutionRepository institutionRepository;

    @Autowired
    InsHotelRoomsTableRepository insHotelRoomsTableRepository;

    @Autowired
    ApiFavoriteTableService favoriteTableService;

    @Autowired
    ApiCommentService commentService;

    @Autowired
    ApiBannerService bannerService;

    @Override
    public XaResult<InstitutionVo> findOne(Long tId, Long userId) throws BusinessException {

        Objects.requireNonNull(tId);

        Institution obj = institutionRepository.findByIdAndStatusNot(tId, XaConstant.Status.delete);
        XaResult<InstitutionVo> xr = new XaResult<InstitutionVo>();
        if (XaUtil.isNotEmpty(obj)) {
            xr.setObject(JSON.parseObject(JSON.toJSONString(obj), InstitutionVo.class));
            xr.getObject().setId(obj.getId());
            LOGGER.info("查询单个实体----->Institution");

            //查询banner
            String sortData1 = "[{property:'sort',direction:'ASC'}]";
            Pageable pageable1 = WebUitl.buildPageRequest(0, JConstant.COMMENT_TOP_NUM, sortData1);
            Map<String, Object> filterParams1 = WebUitl.getParametersStartingWith("{'search_EQ_type':'" + JConstant.BannerType.INSTITUTION_HOURSE + "'}", "search_");
            ;
            XaResult<List<BannerVo>> bannerVos = bannerService.findListNEStatusByFilter(XaConstant.Status.delete, filterParams1, pageable1);
            if (XaUtil.isNotEmpty(bannerVos)) {
                xr.getObject().setInstitution_bannerList(bannerVos.getObject());
            }

            //查询房间
            List<InsHotelRoomsTable> rooms = insHotelRoomsTableRepository.findByInstitutionIdAndStatusNot(tId, XaConstant.Status.delete);
            if (XaUtil.isNotEmpty(rooms)) {
                xr.getObject().setRooms(JSON.parseArray(JSON.toJSONString(rooms), InsHotelRoomsTableVo.class));
            }

            //查询收藏状态
            FavoriteTable favo = null;
            if (XaUtil.isNotEmpty(userId)) {
                favo = favoriteTableService.isFavorite(userId, tId , JConstant.Search_Share_FavType.INSTIBUTION+"").getObject();
            }
            xr.getObject().setFavorite(favo != null ?  XaUtil.getBool(favo.getFavoriteState()) : Boolean.FALSE);
            //设置收藏的id
            xr.getObject().setFavoriteId(favo != null ? XaUtil.getNutNullLong(favo.getId(), null) : null);

            //保存点击量
            obj.setClickCont(1 + NumberUtils.toLong(obj.getClickCont()+""));
            institutionRepository.save(obj);

            //查询institution_commons 前几条 评论
            String sortData2 = "[{property:'createTime',direction:'DESC'}]";
            Pageable pageable2 = WebUitl.buildPageRequest(0, JConstant.COMMENT_TOP_NUM, sortData2);
            Map<String, Object> filterParams2 = WebUitl.getParametersStartingWith(
                    "{'search_EQ_objectId':'" + tId + "'" +
                            ",'search_EQ_commentTypes':'" + JConstant.Order_CommentType.HOURSE + "'}", "search_");
            XaResult<List<CommentVo>> commentsVo = commentService.findInstitutionCommonts(tId, null, pageable2);
            if (XaUtil.isNotEmpty(commentsVo) && commentsVo.getObject() instanceof List && commentsVo.getObject().size() != 0) {
                xr.getObject().setInstitution_commons(commentsVo.getObject());
                //卫生 环境 服务 设施
                double sumHealthClass = 0;
                double sumEnvironmentClass = 0;
                double sumServiceClass = 0;
                double sumFacilityClass = 0;
                for (int i = 0; i < commentsVo.getObject().size(); ++i) {
                    CommentVo vo = commentsVo.getObject().get(i);
                    sumHealthClass += XaUtil.getNutNullDouble(vo.getCommentHealthClass(), COMMENT_SUM_SCORE);
                    sumEnvironmentClass += XaUtil.getNutNullDouble(vo.getCommentEnvironmentClass(),COMMENT_SUM_SCORE );
                    sumServiceClass += XaUtil.getNutNullDouble(vo.getCommentServiceClass(), COMMENT_SUM_SCORE);
                    sumFacilityClass += XaUtil.getNutNullDouble(vo.getCommentFacilityClass(),COMMENT_SUM_SCORE );
                }
                if(commentsVo.getObject().size()==0){
                    xr.getObject().setCommentHealthClass(COMMENT_SUM_SCORE+0.0d);
                    xr.getObject().setCommentEnvironmentClass(COMMENT_SUM_SCORE+0.0d);
                    xr.getObject().setCommentServiceClass(COMMENT_SUM_SCORE+0.0d);
                    xr.getObject().setCommentFacilityClass(COMMENT_SUM_SCORE+0.0d);
                }else{
                    xr.getObject().setCommentHealthClass(sumHealthClass / commentsVo.getObject().size());
                    xr.getObject().setCommentEnvironmentClass(sumEnvironmentClass / commentsVo.getObject().size());
                    xr.getObject().setCommentServiceClass(sumServiceClass / commentsVo.getObject().size());
                    xr.getObject().setCommentFacilityClass(sumFacilityClass / commentsVo.getObject().size());
                }
            } else {
                //卫生 环境 服务 设施
                Double score = Double.parseDouble(COMMENT_SUM_SCORE + "");
                xr.getObject().setCommentHealthClass(score);
                xr.getObject().setCommentEnvironmentClass(score);
                xr.getObject().setCommentServiceClass(score);
                xr.getObject().setCommentFacilityClass(score);
            }
        } else {
            xr.error(XaConstant.Message.object_not_find);
            LOGGER.info(XaConstant.Message.object_not_find);
            throw new BusinessException(XaConstant.Message.object_not_find);
        }
        return xr;
    }

    @Override
    public XaResult<InstitutionVo> findOne(Long tId) throws BusinessException {
       return findOne(tId, null);
    }

    @Override
    public XaResult<List<InstitutionVo>> findListNEStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable)
            throws BusinessException {
        throw new BusinessException(XaConstant.Message.error_method_no_impl);
    }

    @Override
    public XaResult<List<InstitutionVo>> findListEQStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable)
            throws BusinessException {
        XaResult<List<InstitutionVo>> xr = new XaResult<List<InstitutionVo>>();

        StringBuffer csql = new StringBuffer();
        /**
         *
         SELECT ins.id ,ins.institution_name,  ins.institution_Site,  ins.institution_pic,  MIN(hom.hotel_rooms_price) minPirce, hom.hotel_rooms_price_unit , favs.counts favCounts,ins.institution_type,ins.institution_area,ins.sort, ins.click_cont, ins.create_time FROM tb_xa_institution ins
         LEFT JOIN tb_xa_inshotelroomstable hom
         ON ins.id = hom.institution_id
         LEFT JOIN (
         SELECT insti.id, count(insti.id) AS counts FROM tb_xa_institution insti
         LEFT JOIN tb_xa_favoritetable favo ON  favo.favorite_state = 1  AND favo.type = 2 AND favo.favorite_object_id = insti.id
         GROUP BY insti.id
         ) favs
         ON ins.id = favs.id
         WHERE ins.status = 1 AND IFNULL(hom.status , 1) = 1 GROUP BY hom.institution_id ORDER BY ins.id ASC;
         */
        String filterStr = "";
        List<Object> params = new ArrayList<>();
        params.add(status);//ins.status
        if (XaUtil.isNotEmpty(filterParams.get("EQ_institution_Area"))) {
            filterStr = "  AND  ins.institution_area = ? ";
            params.add(filterParams.get("EQ_institution_Area"));
        }
        if (XaUtil.isNotEmpty(filterParams.get("EQ_institution_type"))) {
            filterStr += " AND ins.institution_type = ? ";
            params.add(filterParams.get("EQ_institution_type"));
        }
        if (XaUtil.isNotEmpty(filterParams.get("EQ_sysAreaId"))) {
            filterStr += " AND ins.sys_area_id = ? ";
            params.add(filterParams.get("EQ_sysAreaId"));
        }
        csql.append(" SELECT ins.id ,ins.institution_name,  ins.institution_Site,  ins.institution_pic,  MIN(hom.hotel_rooms_price) minPirce, hom.hotel_rooms_price_unit,hom.is_sell_by_card , favs.counts favCounts , ins.institution_area, ins.institution_type,ins.sort, ins.click_cont, ins.create_time FROM tb_xa_institution ins\n" +
                "        LEFT JOIN tb_xa_inshotelroomstable hom\n" +
                "        ON ins.id = hom.institution_id\n" +
                "        LEFT JOIN (\n" +
                "                SELECT insti.id, count(insti.id) AS counts FROM tb_xa_institution insti\n" +
                "        LEFT JOIN tb_xa_favoritetable favo ON  favo.favorite_state = 1  AND favo.type = 2 AND favo.favorite_object_id = insti.id\n" +
                "        GROUP BY insti.id\n" +
                "            ) favs\n" +
                "        ON ins.id = favs.id\n" +
                "         WHERE ins.status  = ? "+ filterStr +" GROUP BY ins.id  ORDER BY ins.sort asc, ins.click_cont DESC , ins.create_time DESC  ");
        List<Object[]> objs = this.queryParams(csql.toString(), pageable.getPageNumber() * pageable.getPageSize(), pageable.getPageSize(), params);
        List<InstitutionVo> vos = new ArrayList<>();
        for (Object[] obj : objs) {
            InstitutionVo vo = new InstitutionVo();
            vo.setId(((BigInteger) obj[0]).longValue());//??
            vo.setInstitution_Name(XaUtil.getNutNullStr(obj[1]));
            vo.setInstitution_Site(XaUtil.getNutNullStr(obj[2]));
            vo.setInstitution_pic(XaUtil.getNutNullStr(obj[3]));
            vo.setHotelRooms_Price((Double) obj[4]);
            vo.setHotelRooms_Price_unit(XaUtil.getNutNullStr(obj[5]));
            vo.setSellByCard(SqlResultUtil.getSqlResultBool(obj[6]));
            vo.setFavorite_num(XaUtil.getNutNullStr(obj[7], "0"));
            vo.setInstitution_Area(((BigInteger) obj[8]).longValue());
            vo.setInstitution_type(((BigInteger) obj[9]).longValue());
            vo.setSort(SqlResultUtil.getSqlResultLong(obj[10]));
            vo.setClickCont(SqlResultUtil.getSqlResultLong(obj[11]));
            vo.setCreateTime(SqlResultUtil.getSqlResultString(obj[12]));

            vo.setHotelRooms_Price_unit(vo.getSellByCard() ? "卡" : vo.getHotelRooms_Price_unit());

            vos.add(vo);
        }
        xr.setObject(vos);
        return xr;
    }

    @Override
    public XaResult<InstitutionVo> multiOperate(String modelIds,
                                                Integer status) throws BusinessException {
        XaResult<InstitutionVo> xr = new XaResult<InstitutionVo>();
        if (status == null) {
            status = XaConstant.Status.delete;
        }
        if (modelIds != null) {
            String[] ids = modelIds.split(",");
            for (String id : ids) {
                Institution obj = institutionRepository.findByIdAndStatusNot(Long.parseLong(id), status);
                if (XaUtil.isNotEmpty(obj)) {
                    obj.setStatus(status);
                    obj = institutionRepository.save(obj);
                    xr.setObject(JSON.parseObject(JSON.toJSONString(obj), InstitutionVo.class));
                    xr.getObject().setId(obj.getId());
                }
            }
        }
        LOGGER.info("更改数据状态----->Institution");
        return xr;
    }

    @Override
    public XaResult<InstitutionVo> createModel(Institution model)
            throws BusinessException {
        XaResult<InstitutionVo> xr = new XaResult<InstitutionVo>();
        Institution obj = institutionRepository.save(model);
        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), InstitutionVo.class));
        xr.getObject().setId(obj.getId());
        LOGGER.info("新增数据成功----->Institution");
        return xr;
    }

    @Override
    public XaResult<InstitutionVo> updateModel(Institution model)
            throws BusinessException {
        Institution obj = institutionRepository.findOne(model.getId());
        XaResult<InstitutionVo> xr = new XaResult<InstitutionVo>();
        if (XaUtil.isNotEmpty(obj)) {
            obj.setInstitution_Name(XaUtil.isNotEmpty(model.getInstitution_Name()) ? model.getInstitution_Name() : obj.getInstitution_Name());
            obj.setInstitution_Site(XaUtil.isNotEmpty(model.getInstitution_Site()) ? model.getInstitution_Site() : obj.getInstitution_Site());
            obj.setInstitution_TelPhone(XaUtil.isNotEmpty(model.getInstitution_TelPhone()) ? model.getInstitution_TelPhone() : obj.getInstitution_TelPhone());
            obj.setInstitution_Price(XaUtil.isNotEmpty(model.getInstitution_Price()) ? model.getInstitution_Price() : obj.getInstitution_Price());
            obj.setInstitution_Informations(XaUtil.isNotEmpty(model.getInstitution_Informations()) ? model.getInstitution_Informations() : obj.getInstitution_Informations());
            obj.setInstitution_VideoUrl(XaUtil.isNotEmpty(model.getInstitution_VideoUrl()) ? model.getInstitution_VideoUrl() : obj.getInstitution_VideoUrl());
            obj.setInstitution_Area(XaUtil.isNotEmpty(model.getInstitution_Area()) ? model.getInstitution_Area() : obj.getInstitution_Area());
            obj.setInstitution_pic(XaUtil.isNotEmpty(model.getInstitution_pic()) ? model.getInstitution_pic() : obj.getInstitution_pic());
            obj.setInstitution_type(XaUtil.isNotEmpty(model.getInstitution_type()) ? model.getInstitution_type() : obj.getInstitution_type());
            obj.setInstitutionAddress(XaUtil.isNotEmpty(model.getInstitutionAddress()) ? model.getInstitutionAddress() : obj.getInstitutionAddress());
            obj.setSysAreaId(XaUtil.isNotEmpty(model.getSysAreaId()) ? model.getSysAreaId() : obj.getSysAreaId());
            obj.setClickCont(XaUtil.isNotEmpty(model.getClickCont()) ? model.getClickCont() : obj.getClickCont());
            obj.setSort(XaUtil.isNotEmpty(model.getSort()) ? model.getSort() : obj.getSort());
            obj = institutionRepository.save(obj);
            xr.setObject(JSON.parseObject(JSON.toJSONString(obj), InstitutionVo.class));
            xr.getObject().setId(obj.getId());
        } else {
            xr.error(XaConstant.Message.object_not_find);
        }
        LOGGER.info("编辑数据成功----->Institution");
        return xr;
    }

}
